import 'dart:developer';
import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import './common.dart';
import './file_detail_screen.dart';
import 'package:intl/intl.dart';
import 'database_helper.dart';
import 'tencent/cos/cos_helper.dart' as cos_helper;
import 'tencent/cos/config.dart' as cos_config;
import 'tencent/asr/asr_helper.dart' as asr_helper;
import 'package:meeting_note/deepseek/client.dart';
import 'package:flutter_markdown/flutter_markdown.dart';

class MainScreen extends StatefulWidget {
  const MainScreen({super.key});

  @override
  State<MainScreen> createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  int _selectedIndex = 1;

  // file tab fields
  List<FileEntity> files = [];
  bool isLoading = false;
  bool hasMore = true;
  int pageSize = 10;
  int currentPage = 0;
  Timer? _pollingTimer;

  // chat tab fields
  final DeepSeekClient _chatClient = DeepSeekClient();
  final TextEditingController _chatController = TextEditingController();
  final ScrollController _chatScrollController = ScrollController();
  List<Map<String, String>> _chatMessages = [];
  List<_ChatBubble> _chatBubbles = [];
  bool _isChatLoading = false;
  StreamSubscription<StreamingChunk>? _chatStreamSub;
  Set<int> _expandedReasoning = {}; // 展开reasoning的气泡索引
  bool _showInputBar = true;

  @override
  void initState() {
    super.initState();
    _loadMoreFiles();
    _startPolling();
    _chatScrollController.addListener(_handleChatScroll);
  }

  @override
  void dispose() {
    _pollingTimer?.cancel();
    _chatController.dispose();
    _chatScrollController.dispose();
    _chatStreamSub?.cancel();
    super.dispose();
  }

  void _startPolling() {
    _pollingTimer?.cancel();
    _pollingTimer = Timer.periodic(const Duration(seconds: 5), (timer) {
      _pollProcessingFiles();
    });
  }

  Future<void> _pollProcessingFiles() async {
    final processingFiles =
        files.where((f) => f.status == FileStatus.processing).toList();
    if (processingFiles.isEmpty) {
      return;
    }

    for (var file in processingFiles) {
      try {
        if (file.taskId == null) {
          continue;
        }

        asr_helper.AsrConfig config = asr_helper.AsrConfig(
          secretId: cos_config.CosConfig.secretId,
          secretKey: cos_config.CosConfig.secretKey,
          region: cos_config.CosConfig.region,
        );
        log('轮询任务状态, taskId: ${file.taskId}');
        Map<String, dynamic> result = await asr_helper.AsrClient(
          config: config,
        ).describeTaskStatus(file.taskId!);
        log('轮询任务状态结果: $result');

        final status = result['Response']?['Data']?['Status'] as int?;
        final resultText = result['Response']?['Data']?['Result'] as String?;

        log('轮询任务状态: $status');
        if (status == 2) {
          // 任务成功
          String textContent = utf8.decode((resultText ?? '').codeUnits);
          // List<TextContentEntity> textContentList = [];
          // for (var item in textContent.split(';')) {
          //   final startTime = item.split(',')[0];
          //   final endTime = item.split(',')[1];
          //   final content = item.split(',')[2];
          //   textContentList.add(TextContentEntity(startTime: startTime, endTime: endTime, content: content));
          // }

          await DatabaseHelper().updateFileTextContent(file.id!, textContent);
          if (mounted) {
            setState(() {
              final index = files.indexWhere((f) => f.id == file.id);
              if (index != -1) {
                files[index] = file.copyWith(
                  status: FileStatus.success,
                  textContent: textContent,
                );
              }
            });
          }
        } else if (status == 3) {
          // 任务失败
          final errMsg =
              result['Response']?['Data']?['ErrorMsg'] as String? ?? '识别失败';
          await DatabaseHelper().updateFileStatus(
            file.id!,
            FileStatus.failed,
            errMsg,
          );
          if (mounted) {
            setState(() {
              final index = files.indexWhere((f) => f.id == file.id);
              if (index != -1) {
                files[index] = file.copyWith(
                  status: FileStatus.failed,
                  errMsg: errMsg,
                );
              }
            });
          }
        }
      } catch (e) {
        log('轮询任务状态失败: ${e.toString()}');
        await DatabaseHelper().updateFileStatus(
          file.id!,
          FileStatus.failed,
          e.toString(),
        );
        if (mounted) {
          setState(() {
            final index = files.indexWhere((f) => f.id == file.id);
            if (index != -1) {
              files[index] = file.copyWith(
                status: FileStatus.failed,
                errMsg: e.toString(),
              );
            }
          });
        }
      }
    }
  }

  Future<void> selectFile() async {
    final result = await FilePicker.platform.pickFiles();
    if (result != null) {
      int fileID = await DatabaseHelper().insertFile(
        FileEntity(
          userName: '1',
          fileName: result.files.single.name,
          path: result.files.single.path!,
          status: FileStatus.pending,
        ),
      );

      final fileEntity = await DatabaseHelper().getFileById(fileID);
      if (fileEntity == null) {
        log('文件插入失败，ID: $fileID');
        throw Exception('文件插入失败，ID: $fileID');
      }

      setState(() {
        files = [fileEntity, ...files];
        log('添加文件: ${result.files.single.name}, 当前文件数: ${files.length}');
      });
    }
  }

  Color getStatusColor(String status) {
    switch (status) {
      case FileStatus.pending:
        return Colors.orange;
      case FileStatus.processing:
        return Colors.blue;
      case FileStatus.success:
        return Colors.green;
      case FileStatus.failed:
        return Colors.red;
      default:
        return Colors.grey;
    }
  }

  void _sendChat() async {
    final input = _chatController.text.trim();
    if (input.isEmpty || _isChatLoading) return;
    setState(() {
      _chatMessages.add({"role": "user", "content": input});
      _chatBubbles.add(_ChatBubble(role: "user", content: input));
      _isChatLoading = true;
      _chatController.clear();
    });

    // 新增：每次用户输入后立即滚动到底部
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _chatScrollController.animateTo(
        _chatScrollController.position.maxScrollExtent,
        duration: const Duration(milliseconds: 200),
        curve: Curves.easeOut,
      );
    });

    String assistantContent = '';
    String reasoningContent = '';
    bool reasoningDone = false;
    _chatBubbles.add(
      _ChatBubble(
        role: "assistant",
        content: '',
        reasoning: '',
        reasoningDone: false,
      ),
    );

    _chatStreamSub = _chatClient
        .streamChatCompletions(messages: _chatMessages)
        .listen(
          (chunk) {
            setState(() {
              final lastIdx = _chatBubbles.lastIndexWhere(
                (b) => b.role == "assistant",
              );
              if (chunk.type == 'reasoning') {
                reasoningContent += chunk.data;
                if (lastIdx != -1) {
                  _chatBubbles[lastIdx] = _chatBubbles[lastIdx].copyWith(
                    reasoning: reasoningContent,
                    reasoningDone: false,
                  );
                }
              } else if (chunk.type == 'content') {
                assistantContent += chunk.data;
                if (lastIdx != -1) {
                  _chatBubbles[lastIdx] = _chatBubbles[lastIdx].copyWith(
                    content: assistantContent,
                    reasoningDone: true,
                  );
                }
              }
            });
            WidgetsBinding.instance.addPostFrameCallback((_) {
              _chatScrollController.animateTo(
                _chatScrollController.position.maxScrollExtent,
                duration: const Duration(milliseconds: 200),
                curve: Curves.easeOut,
              );
            });
          },
          onDone: () {
            setState(() {
              _isChatLoading = false;
              _chatMessages.add({
                "role": "assistant",
                "content": assistantContent,
              });
            });
          },
          onError: (e) {
            setState(() {
              _isChatLoading = false;
            });
          },
        );
  }

  void _handleChatScroll() {
    // 隐藏输入框：向上滑动时隐藏，滑到底部显示
    if (!_chatScrollController.hasClients) return;
    final atBottom =
        _chatScrollController.offset >=
        _chatScrollController.position.maxScrollExtent - 10;
    if (_showInputBar != atBottom) {
      setState(() {
        _showInputBar = atBottom;
      });
    }
  }

  Widget _buildChatTab() {
    return Column(
      children: [
        Expanded(
          child: ListView.builder(
            controller: _chatScrollController,
            itemCount: _chatBubbles.length,
            itemBuilder: (context, idx) {
              final bubble = _chatBubbles[idx];
              final isUser = bubble.role == "user";
              return Container(
                margin: const EdgeInsets.symmetric(vertical: 6, horizontal: 12),
                alignment:
                    isUser ? Alignment.centerRight : Alignment.centerLeft,
                child: Column(
                  crossAxisAlignment:
                      isUser
                          ? CrossAxisAlignment.end
                          : CrossAxisAlignment.start,
                  children: [
                    if (bubble.reasoning.isNotEmpty)
                      _ReasoningWidget(
                        text: bubble.reasoning,
                        expanded: _expandedReasoning.contains(idx),
                        onToggle: () {
                          setState(() {
                            if (_expandedReasoning.contains(idx)) {
                              _expandedReasoning.remove(idx);
                            } else {
                              _expandedReasoning.add(idx);
                            }
                          });
                        },
                        reasoningDone: bubble.reasoningDone,
                      ),
                    Container(
                      padding: const EdgeInsets.symmetric(
                        vertical: 8,
                        horizontal: 12,
                      ),
                      decoration: BoxDecoration(
                        color:
                            isUser
                                ? Theme.of(context).colorScheme.primary
                                : Colors.grey.shade100,
                        borderRadius: BorderRadius.circular(12),
                      ),
                      child:
                          isUser
                              ? Text(
                                bubble.content,
                                style: TextStyle(
                                  color:
                                      Theme.of(context).colorScheme.onPrimary,
                                  fontSize: 16,
                                ),
                              )
                              : MarkdownBody(
                                data: bubble.content,
                                styleSheet: MarkdownStyleSheet(
                                  p: const TextStyle(
                                    fontSize: 16,
                                    color: Colors.black87,
                                  ),
                                ),
                              ),
                    ),
                  ],
                ),
              );
            },
          ),
        ),
        // 输入框区域始终显示
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
          child: Row(
            children: [
              Expanded(
                child: TextField(
                  controller: _chatController,
                  enabled: !_isChatLoading,
                  decoration: const InputDecoration(
                    hintText: "请输入内容...",
                    border: OutlineInputBorder(),
                    isDense: true,
                  ),
                  onSubmitted: (_) => _sendChat(),
                ),
              ),
              const SizedBox(width: 8),
              IconButton(
                icon:
                    _isChatLoading
                        ? const SizedBox(
                          width: 24,
                          height: 24,
                          child: CircularProgressIndicator(strokeWidth: 2),
                        )
                        : const Icon(Icons.send),
                onPressed: _isChatLoading ? null : _sendChat,
              ),
            ],
          ),
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_selectedIndex == 0 ? 'Chat' : '会议纪要'),
        backgroundColor: Theme.of(context).colorScheme.primary,
        foregroundColor: Theme.of(context).colorScheme.onPrimary,
        actions:
            _selectedIndex == 1
                ? [
                  PopupMenuButton<String>(
                    onSelected: (value) async {
                      if (value == 'reset_db') {
                        await DatabaseHelper().resetDatabase();
                        await _loadMoreFiles();
                        setState(() {
                          files.clear();
                          currentPage = 0;
                          hasMore = true;
                        });
                      }
                    },
                    itemBuilder:
                        (BuildContext context) => [
                          const PopupMenuItem<String>(
                            value: 'reset_db',
                            child: Text('重置数据库'),
                          ),
                        ],
                  ),
                ]
                : null,
      ),
      body: IndexedStack(
        index: _selectedIndex,
        children: [_buildChatTab(), buildBody()],
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: (index) {
          setState(() {
            _selectedIndex = index;
          });
        },
        items: [
          BottomNavigationBarItem(
            icon: Icon(
              _selectedIndex == 0
                  ? Icons.chat_bubble
                  : Icons.chat_bubble_outline,
            ),
            label: 'Chat',
          ),
          BottomNavigationBarItem(
            icon: Icon(_selectedIndex == 1 ? Icons.folder : Icons.folder_open),
            label: 'File',
          ),
        ],
      ),
      floatingActionButton:
          _selectedIndex == 1
              ? FloatingActionButton(
                onPressed: _uploadFile,
                backgroundColor: Theme.of(context).colorScheme.primary,
                foregroundColor: Theme.of(context).colorScheme.onPrimary,
                child: const Icon(Icons.upload),
                tooltip: '上传文件',
              )
              : null,
    );
  }

  Widget buildBody() {
    return NotificationListener<ScrollNotification>(
      onNotification: (ScrollNotification scrollInfo) {
        if (!isLoading &&
            hasMore &&
            scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) {
          _loadMoreFiles();
        }
        return false;
      },
      child: ListView.builder(
        shrinkWrap: true,
        physics: const AlwaysScrollableScrollPhysics(),
        key: ValueKey(files.length),
        itemCount: files.length + (hasMore ? 1 : 0),
        itemBuilder: (context, index) {
          if (index >= files.length) {
            return const Center(
              child: Padding(
                padding: EdgeInsets.all(8.0),
                child: Text('没有更多文件了哦~'),
              ),
            );
          }
          final file = files[index];
          return Card(
            key: ValueKey(file.fileName!),
            margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
            child: ListTile(
              leading:
                  file.fileName!.toLowerCase().contains('.mp3') ||
                          file.fileName!.toLowerCase().contains('.wav')
                      ? const Icon(Icons.music_note, color: Colors.deepPurple)
                      : const Icon(
                        Icons.insert_drive_file,
                        color: Colors.deepPurple,
                      ),
              title: Row(
                children: [
                  Expanded(
                    child: Text(
                      file.fileName!,
                      style: const TextStyle(fontWeight: FontWeight.w500),
                    ),
                  ),
                  if (file.status == FileStatus.pending)
                    OutlinedButton.icon(
                      onPressed: () {
                        submitFile(file, index);
                      },
                      icon: const Icon(Icons.text_snippet, size: 16),
                      label: const Text('生成文本', style: TextStyle(fontSize: 14)),
                      style: OutlinedButton.styleFrom(
                        padding: const EdgeInsets.symmetric(
                          horizontal: 8,
                          vertical: 4,
                        ),
                        side: BorderSide(
                          color: Theme.of(context).colorScheme.primary,
                        ),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(8),
                        ),
                      ),
                    ),
                  if (file.status == FileStatus.processing)
                    Padding(
                      padding: const EdgeInsets.only(left: 8.0),
                      child: SizedBox(
                        width: 20,
                        height: 20,
                        child: CircularProgressIndicator(
                          strokeWidth: 2.5,
                          valueColor: AlwaysStoppedAnimation<Color>(
                            Colors.blue,
                          ),
                        ),
                      ),
                    ),
                ],
              ),
              subtitle: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    DateFormat('yyyy-MM-dd HH:mm').format(
                      DateTime.fromMillisecondsSinceEpoch(file.createdAt!),
                    ),
                  ),
                  Text(
                    file.status!,
                    style: TextStyle(
                      color: getStatusColor(file.status!),
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                ],
              ),
              onTap:
                  () => Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => FileDetailScreen(file: file),
                    ),
                  ),
            ),
          );
        },
      ),
    );
  }

  Future<void> _loadMoreFiles() async {
    if (isLoading) return;
    setState(() => isLoading = true);

    final dbFiles = await DatabaseHelper().getAllFiles(
      pageSize,
      currentPage * pageSize,
    );
    log('从数据库加载文件: $dbFiles');
    if (dbFiles.isEmpty) {
      setState(() => hasMore = false);
    } else {
      setState(() {
        files.addAll(
          dbFiles.map((f) {
            log('从数据库加载文件: $f');
            return f;
          }),
        );
        currentPage++;
      });
    }

    setState(() => isLoading = false);
  }

  void submitFile(FileEntity file, int fileIndex) async {
    String fileName = file.fileName!;
    await cos_helper.putAudioFile(cosPath: "/$fileName", srcPath: file.path!);
    try {
      String cosUrl = await cos_helper.generatePresignedUrl(
        bucket: cos_config.CosConfig.bucket,
        cosPath: "/$fileName",
        signValidTime: 600, // 有效期为 10 分钟
      );
      log(cosUrl);
      asr_helper.AsrConfig config = asr_helper.AsrConfig(
        secretId: cos_config.CosConfig.secretId,
        secretKey: cos_config.CosConfig.secretKey,
        region: cos_config.CosConfig.region,
      );
      Map<String, dynamic> result = await asr_helper.AsrClient(
        config: config,
      ).createRecTask(url: cosUrl);
      log("$result");
      final taskId = result['Response']?['Data']?['TaskId'] as int?;
      if (taskId == null) {
        String errMsg =
            result['Response']?['Error']?['Message'] as String? ?? '未知错误';
        log('创建识别任务失败: $errMsg');
        await DatabaseHelper().updateFileStatus(
          file.id!,
          FileStatus.failed,
          errMsg,
        );
        setState(() {
          files[fileIndex] = file.copyWith(
            status: FileStatus.failed,
            errMsg: errMsg,
          );
        });
        return;
      }
      log('创建识别任务成功，TaskId: $taskId');
      await DatabaseHelper().updateFileStatus(
        file.id!,
        FileStatus.processing,
        '',
        taskId: taskId,
      );
      setState(() {
        files[fileIndex] = file.copyWith(
          status: FileStatus.processing,
          taskId: taskId,
        );
      });
    } catch (e) {
      log(e.toString());
      await DatabaseHelper().updateFileStatus(
        file.id!,
        FileStatus.failed,
        e.toString(),
      );
      setState(() {
        files[fileIndex] = file.copyWith(
          status: FileStatus.failed,
          errMsg: e.toString(),
        );
      });
      return;
    }
  }

  Future<void> _uploadFile() async {
    final result = await FilePicker.platform.pickFiles();
    if (result != null) {
      int fileID = await DatabaseHelper().insertFile(
        FileEntity(
          userName: '1',
          fileName: result.files.single.name,
          path: result.files.single.path!,
          status: FileStatus.pending,
        ),
      );

      final fileEntity = await DatabaseHelper().getFileById(fileID);
      if (fileEntity == null) {
        log('文件插入失败，ID: $fileID');
        throw Exception('文件插入失败，ID: $fileID');
      }

      setState(() {
        files = [fileEntity, ...files];
        log('添加文件: ${result.files.single.name}, 当前文件数: ${files.length}');
      });
    }
  }
}

// 聊天气泡模型
class _ChatBubble {
  final String role; // "user" or "assistant"
  final String content;
  final String reasoning;
  final bool reasoningDone;

  _ChatBubble({
    required this.role,
    required this.content,
    this.reasoning = '',
    this.reasoningDone = false,
  });

  _ChatBubble copyWith({
    String? content,
    String? reasoning,
    bool? reasoningDone,
  }) {
    return _ChatBubble(
      role: role,
      content: content ?? this.content,
      reasoning: reasoning ?? this.reasoning,
      reasoningDone: reasoningDone ?? this.reasoningDone,
    );
  }
}

// reasoning折叠组件
class _ReasoningWidget extends StatelessWidget {
  final String text;
  final bool expanded;
  final VoidCallback onToggle;
  final bool reasoningDone;

  const _ReasoningWidget({
    required this.text,
    required this.expanded,
    required this.onToggle,
    required this.reasoningDone,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final lines = text.split('\n');
    final showExpand = lines.length > 4;
    final displayLines =
        showExpand && !expanded ? lines.sublist(lines.length - 4) : lines;

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.only(left: 2, bottom: 2),
          child: Text(
            reasoningDone ? '已思考' : '思考中',
            style: TextStyle(
              fontSize: 12,
              color: reasoningDone ? Colors.green : Colors.deepOrange,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
        Container(
          padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
          decoration: BoxDecoration(
            color: Colors.grey.shade200,
            borderRadius: BorderRadius.circular(8),
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                displayLines.join('\n'),
                style: const TextStyle(fontSize: 13, color: Colors.blueGrey),
                maxLines: expanded ? null : 4,
                overflow:
                    expanded ? TextOverflow.visible : TextOverflow.ellipsis,
              ),
              if (showExpand)
                Align(
                  alignment: Alignment.centerRight,
                  child: GestureDetector(
                    onTap: onToggle,
                    child: Padding(
                      padding: const EdgeInsets.only(top: 2, right: 2),
                      child: Text(
                        expanded ? '收起' : '展开',
                        style: TextStyle(
                          color: Theme.of(context).colorScheme.primary,
                          fontSize: 12,
                          fontWeight: FontWeight.w500,
                        ),
                      ),
                    ),
                  ),
                ),
            ],
          ),
        ),
      ],
    );
  }
}
